#include "include/shader.h"

Shader::Shader(const std::string& vertexCode, const std::string& fragmentCode) {
  const char* vertexShaderSource = vertexCode.c_str();
  const char* fragmentShaderSource = fragmentCode.c_str();
  GLuint vertex, fragment;
  vertex = glCreateShader(GL_VERTEX_SHADER);
  fragment = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(vertex, 1, &vertexShaderSource, NULL);
  glShaderSource(fragment, 1, &fragmentShaderSource, NULL);

  glCompileShader(vertex);
  checkShaderErrors(vertex, "COMPILE");

  glCompileShader(fragment);
  checkShaderErrors(fragment, "COMPILE");
  mProgram = glCreateProgram();

  glAttachShader(mProgram, vertex);
  glAttachShader(mProgram, fragment);
  glLinkProgram(mProgram);

  checkShaderErrors(mProgram, "LINK");

  glDeleteShader(vertex);
  glDeleteShader(fragment);
}
Shader::~Shader() {}

void Shader::begin() { GL_CALL(glUseProgram(mProgram)); }

void Shader::end() { GL_CALL(glUseProgram(0)); }

void Shader::checkShaderErrors(GLuint target, std::string type) {
  int success = 0;
  char infoLog[1024];

  if (type == "COMPILE") {
    glGetShaderiv(target, GL_COMPILE_STATUS, &success);
    if (!success) {
      glGetShaderInfoLog(target, 1024, NULL, infoLog);
      __android_log_print(ANDROID_LOG_ERROR, "fhq",
                          "Shader compile failed:\n%s", infoLog);
    }
  } else if (type == "LINK") {
    glGetProgramiv(target, GL_LINK_STATUS, &success);
    if (!success) {
      glGetProgramInfoLog(target, 1024, NULL, infoLog);
      __android_log_print(ANDROID_LOG_ERROR, "fhq", "Shader link failed:\n%s",
                          infoLog);
    }
  } else {
    std::cout << "Error: Check shader errors Type is wrong" << std::endl;
  }
}